#include "test.h"
#include "cpu_instr.h"
#include "types.h"
#include "list.h"
#include "log.h"

// Function to trigger breakpoint exception
void trigger_breakpoint(void)
{
    __asm__ volatile("int $3");
}
// Function to trigger overflow exception
void trigger_overflow(void)
{
    int a = 0x7FFFFFFF;    // Maximum value for a 32 - bit signed integer
    int b = 1;
    int result;
    __asm__ volatile("addl %2, %1\n\t"
                     "into\n\t"
                     : "=r"(result)
                     : "r"(a), "r"(b)
                     : "cc");
}
// Function to trigger invalid opcode exception
void trigger_invalid_opcode(void)
{
    __asm__ __volatile__(".byte 0x0F, 0x0B");    // Invalid opcode
}
void trigger_nmi(void)
{
    __asm__ __volatile__("cli");
    uint8_t port_61 = inb(0x61);
    port_61 ^= 0x80;
    outb(0x61, port_61);

    __asm__ __volatile__("mov $0x80, %al\n\t"
                         "out %al, $0x70\n\t"    // 向 0x70 写入 0x80（启用 NMI）
                         "mov $0x00, %al\n\t"
                         "out %al, $0x71\n\t"    // 向 0x71 写入 0x00（触发 NMI）
    );
}
void node_show(list_node_t *node)
{
    log_printf("node:%x", node);
}
void list_test(void)
{
    list_t list;
    list_init(&list);
    log_printf("list test");
    log_printf("list :%x", (uint32_t)&list);
    log_printf("list count:%d", list.count);
    log_printf("list first:%x", list.first);
    log_printf("list last:%x", list.last);
    log_printf("list node size:%d", sizeof(list_node_t));
    list_node_t nodes[5];
    for (int i = 0; i < 5; i++)
    {
        list_node_init(&nodes[i]);
        log_printf("list node %d :%x", i, &nodes[i]);
        list_insert_first(&list, &nodes[i]);
    }
    log_printf("list count:%d", list.count);
    list_traverse(&list, node_show);
    list_init(&list);
    for (int i = 0; i < 5; i++)
    {
        list_insert_last(&list, &nodes[i]);
    }
    log_printf("list count:%d", list.count);
    list_traverse(&list, node_show);

    list_node_t *first = list_remove_first(&list);
    list_node_t *last  = list_remove_last(&list);
    list_node_t *node  = list_remove(&list, &nodes[2]);
    log_printf("remove first and last and node[2]:%x,%x,%x", first, last, node);
    log_printf("list count:%d", list.count);
    list_traverse(&list, node_show);
    struct _my_node_t
    {
        int         a;
        int         b;
        list_node_t node;
    } my_node;
    my_node.a = 1;
    list_node_init(&my_node.node);
    log_printf("my_node node:%x", (uint32_t)&my_node.node);
    log_printf("my_node :%x", (uint32_t)&my_node);
    struct _my_node_t *aa = container_of(&my_node.node, struct _my_node_t, node);
    log_printf("aa:%x", (uint32_t)aa);
    log_printf("aa->a:%d", aa->a);
    log_printf("if node=0x0: %x", container_of((list_node_t *)0, struct _my_node_t, node));
    log_printf("%x:", 0x0);
}